package com.hjs.消费者生产者.方式三;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ProducerConsumerWithLock {
    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        Condition producerCondition = lock.newCondition();
        Condition consumerCondition = lock.newCondition();
        Resource resource = new Resource(lock, producerCondition, consumerCondition);
        //生产者线程
        ProducerThread2 producer1 = new ProducerThread2(resource);
        //消费者线程
        ConsumerThread2 consumer1 = new ConsumerThread2(resource);
        ConsumerThread2 consumer2 = new ConsumerThread2(resource);
        ConsumerThread2 consumer3 = new ConsumerThread2(resource);
        producer1.start();
        consumer1.start();
        consumer2.start();
        consumer3.start();
    }

    static class Resource {
        private int num = 0;
        private int size = 10;
        private Lock lock;
        private Condition porducerCondition;
        private Condition consumerConditonn;

        public Resource(Lock lock, Condition porducerCondition, Condition consumerConditonn) {
            this.lock = lock;
            this.porducerCondition = porducerCondition;
            this.consumerConditonn = consumerConditonn;
        }

        public void add() {
            lock.lock();
            try {
                if (num < size) {
                    num++;
                    System.out.println(Thread.currentThread().getName() + "生产了一个商品，当前产品数量为" + num);
                    consumerConditonn.signalAll();
                } else {



                    try {
                        porducerCondition.await();
                        System.out.println(Thread.currentThread().getName() + "线程进入等待状态");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }


                }
            } finally {
                lock.unlock();
            }
        }

        public void remove() {
            lock.unlock();
            try {
                if (num > 0) {
                    num--;
                    System.out.println(Thread.currentThread().getName() + "消费了一件商品，当前还剩" + num + "件");
                    porducerCondition.signalAll();
                } else {
                    try {
                        consumerConditonn.await();
                        System.out.println(Thread.currentThread().getName() + "进入了等待");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            } finally {
                lock.unlock();
            }
        }
    }

    static class ConsumerThread2 extends Thread {
        private Resource resource;

        public ConsumerThread2(Resource resource) {
            this.resource = resource;
            //setName("消费者");
        }

        public void run() {
            while (true) {
                try {
                    Thread.sleep((long) (1000 * Math.random()));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                resource.remove();
            }
        }
    }

    static class ProducerThread2 extends Thread {
        private Resource resource;

        public ProducerThread2(Resource resource) {
            this.resource = resource;
            setName("生产者");
        }

        public void run() {
            while (true) {
                try {
                    Thread.sleep((long) (1000 * Math.random()));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                resource.add();
            }
        }
    }

}
